// SkyDome.cpp: implementation of the SkyDome class.
//
//////////////////////////////////////////////////////////////////////

#include "SkyDome.h"

static sgVec4 black             = { 0.0f, 0.0f, 0.0f, 1.0f } ;

static sgVec4 base_sky_color    = { 0.39f, 0.50f, 0.74f, 1.0f } ;

static sgVec4 base_ambient      = { 0.2f, 0.2f, 0.2f, 1.0f } ;
static sgVec4 base_diffuse      = { 1.0f, 1.0f, 1.0f, 1.0f } ;
static sgVec4 base_specular     = { 1.0f, 1.0f, 1.0f, 1.0f } ;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

SkyDome::SkyDome(int nstars, sgdVec3* star_data)
{
  /* values needed to compute brightness */
  m_log01 = -log( 0.01 );
  sqrt_m_log01 = sqrt( m_log01 );
	
  /* sky */
  sky       =  new ssgaSky ;
  sky       -> build ( HOR_RADIUS, VER_RADIUS, 0/*nplanets*/, NULL/*planet_data*/, nstars, star_data);

  /* Default camera position */
  this->campos.xyz[SG_X]		= 0.0f;
  this->campos.xyz[SG_Y]		= 0.0f;
  this->campos.xyz[SG_Z]		= 0.0f;
  this->campos.hpr[HEADING]		= 0.0f;
  this->campos.hpr[PITCH]	  	= 0.0f;
  this->campos.hpr[ROLL]		= 0.0f;

  /* Number of stars */
  this->nstars = nstars;
  sgdCopyVec3(this->star_data,*(star_data));

  this->sky_brightness = 0.5;
}

SkyDome::~SkyDome()
{

}

ssgaSky* SkyDome::getSky(void)
{
	return this->sky;
}

void SkyDome::setBrightness(double sol_angle)
{
  this->sol_angle = sol_angle;
  this->sky_brightness = (1.0f + (float)cos(this->sol_angle))/2.0f; 
}

void SkyDome::update(float dt)
{
  /* update sky */
  sky -> repositionFlat ( campos.xyz, 0, dt );
  sky -> modifyVisibility ( campos.xyz[SG_Z], dt );

  this->scene_brightness = pow(this->sky_brightness,0.5);

  /* set sky color */
  sky_color[0] = base_sky_color[0] * sky_brightness;
  sky_color[1] = base_sky_color[1] * sky_brightness;
  sky_color[2] = base_sky_color[2] * sky_brightness;
  sky_color[3] = base_sky_color[3];

  /* repaint the sky */
  sky -> repaint ( sky_color, fog_color, cloud_color, sol_angle, 0/*nplanets*/, NULL/*planet_data*/, nstars, &(star_data));

   /* set light source */
  sgCoord solpos;
  sky-> getBody (1) -> getPosition ( & solpos );
  ssgGetLight ( 0 ) -> setPosition ( solpos.xyz ) ;

  scene_ambient[0] = base_ambient[0] * (float)scene_brightness;
  scene_ambient[1] = base_ambient[1] * (float)scene_brightness;
  scene_ambient[2] = base_ambient[2] * (float)scene_brightness;
  scene_ambient[3] = 1.0;

  scene_diffuse[0] = base_diffuse[0] * (float)scene_brightness;
  scene_diffuse[1] = base_diffuse[1] * (float)scene_brightness;
  scene_diffuse[2] = base_diffuse[2] * (float)scene_brightness;
  scene_diffuse[3] = 1.0;

  scene_specular[0] = base_specular[0] * (float)scene_brightness;
  scene_specular[1] = base_specular[1] * (float)scene_brightness;
  scene_specular[2] = base_specular[2] * (float)scene_brightness;
  scene_specular[3] = 1.0;
  // GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if
  // we only update GL_AMBIENT for our lights we will never get
  // a completely dark scene.  So, we set GL_LIGHT_MODEL_AMBIENT
  // explicitely to black.
  glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
  ssgGetLight( 0 ) -> setColour( GL_AMBIENT, scene_ambient );
  ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, scene_diffuse );
  ssgGetLight( 0 ) -> setColour( GL_SPECULAR, scene_specular );
}

void SkyDome::setCampos(sgCoord* newCampos)
{
sgCopyCoord(&(this->campos),newCampos);
}

void SkyDome::setCloudColor(sgVec4 cc)
{
	sgCopyVec4((this->cloud_color),(cc));
}

void SkyDome::setFogColor(sgVec4 fc)
{
	sgCopyVec4((this->fog_color),(fc));
}

void SkyDome::preDraw()
{
	this->sky->preDraw();
}

void SkyDome::postDraw()
{
	this->sky->postDraw(this->campos.xyz[SG_Z] );
}

float SkyDome::getSkyBrightness()
{
return this->sky_brightness;
}
